var c = document.getElementById('c');
var ctx = c.getContext('2d');
c.width = window.innerWidth * window.devicePixelRatio;
c.height = window.innerHeight * window.devicePixelRatio;

/**
 * 常用三角函数包括三个：sin(a), cos(a), tan(a)，其中a是角度数值，这是数学上的三角函数，
 * javascript中相应表示为：
 *      1. sin(a) <==> Math.sin(a * Math.PI / 180);
 *      2. cos(a) <==> Math.cos(a * Math.PI / 180);
 *      3. tan(a) <==> Math.tan(a * Math.PI / 180);
 * 三角函数通常用于已知角度求双边比值，但web中，更常用的是已知双边比值求角度，此时，要用到反三角函数。
 * 常用反三角函数包括：arcsin(x/R), arccos(y/R), arctan(x/y)，
 * 在javascript中相应表示为：
 *      1. arcsin(x/R) <==> Math.asin(x/R) * (180 / Math.PI);
 *      2. arccos(y/R) <==> Math.acos(y/R) * (180 / Math.PI);
 *      3. arctan(x/y) <==> Math.atan(x/y) * (180 / Math.PI);
 * 以上所有用到角度的地方均乘上了 Maht.PI / 180 或者 180 / Math.PI，
 * 这是因为canvas中的角度均使用弧度制表示。
 * 
 * 在使用反三角函数求角度时，最常使用的便是arctan(x/y)函数，因为此函数只需两个直角边便可得到结果角度，
 * 在坐标系中，这两条直角边往往就是特定点的坐标值，容易获得。
 * JavaScript提供了对应的函数，Math.atan(x/y)。
 * 但此函数有一个问题，我们知道arctan函数作用域为(-PI/2, PI/2)，这样atan函数得到结果就有互为相反数的两个结果。
 * 为了解决这一问题，javascript提供了：
 *      atan2(x, y)
 * 函数，只需传入指定点，便能得到于x轴夹角对应角度
 */

 /**
  * 箭头类
  */
function Arrow(x, y, rotation) {
    this.x = x || 0;
    this.y = y || 0;
    this.rotation = rotation || 0;
}
Arrow.prototype = {
    draw: function() {
        ctx.save();
        ctx.translate(this.x, this.y);
        ctx.rotate(this.rotation);
        ctx.fillStyle = 'rgb(255, 255, 0)';
        ctx.strokeStyle = 'rgb(0, 0, 0)';
        ctx.lineWidth = 5;
        ctx.beginPath();
        ctx.moveTo(0, 50);
        ctx.lineTo(50, 0);
        ctx.lineTo(25, 0);
        ctx.lineTo(25, -50);
        ctx.lineTo(-25, -50);
        ctx.lineTo(-25, 0);
        ctx.lineTo(-50, 0);
        ctx.closePath();
        ctx.stroke();
        ctx.fill();
        ctx.restore();
    }
}

function init() {
    var arrows = [];
    arrows.push(new Arrow(c.width / 2, c.height / 2, 0));

    //添加事件处理
    c.addEventListener('mousedown', handleMouseDown, false);
    
    //鼠标按下处理函数
    function handleMouseDown(e) {
        var event = e || window.event;
        var mousePoint = getMousePoint(event);
        arrows.push(new Arrow(mousePoint.x, mousePoint.y, 0));
        c.addEventListener('mousemove', handleMouseMove, false);
        c.addEventListener('mouseup', handleMouseUp, false);
    }

    //鼠标移动处理函数
    function handleMouseMove(e) {
        var event = e || window.event;
        var mousePoint = getMousePoint(event);
        for(var i = 0; i < arrows.length; i += 1) {
            var deg = Math.atan2(mousePoint.x - arrows[i].x, mousePoint.y - arrows[i].y);
            arrows[i].rotation = -deg;   
        }
        return false;
    }

    //鼠标抬起处理函数
    function handleMouseUp(e) {
        var event = e || window.e;
        c.removeEventListener('mousemove', handleMouseMove);
        c.removeEventListener('mouseup', handleMouseUp);
        return false;
    }

    //根据鼠标事件对象获取当前鼠标page坐标
    function getMousePoint(e) {
        var x, y;
        var element = e.target;
        if(e.pageX||e.pageY) {
            x = e.pageX;
            y = e.pageY;
        } else {
            x = event.clientX + document.body.scrollLeft +document.documentElement.scrollLeft;
            y = event.clientY + document.body.scrollTop +document.documentElement.scrollTop;
        }
        x -= element.offsetLeft;
        y -= element.offsetTop;
        return {x: x, y: y};
    }
    
    for(var i = 0; i < arrows.length; i += 1) {
        arrows[i].draw();
    }

    //动画函数
    function animate() {
        requestAnimationFrame(animate);

        ctx.fillStyle = 'rgb(230, 230, 230)';
        ctx.fillRect(0, 0, c.width, c.height);

        for(var i = 0; i < arrows.length; i += 1) {
            arrows[i].draw();
        }
    }
    animate();

}

init();